package nancal.mp.config.filter


import nancal.mp.config.base.BaseFilter
import nancal.mp.db.redis.rer
import nancal.mp.findParameterValue
import nbcp.base.comm.config
import nbcp.base.db.LoginUserModel
import nbcp.base.extend.AsBooleanWithNull
import nbcp.base.extend.AsString
import nbcp.base.extend.HasValue
import nbcp.base.extend.Important
import nbcp.base.utils.UrlUtil
import org.slf4j.LoggerFactory
import org.springframework.cloud.gateway.filter.GatewayFilterChain
import org.springframework.cloud.gateway.filter.GlobalFilter
import org.springframework.context.annotation.Configuration
import org.springframework.core.Ordered
import org.springframework.http.server.reactive.ServerHttpRequest
import org.springframework.web.server.ServerWebExchange
import reactor.core.publisher.Mono

@Configuration
class TokenFilter : BaseFilter(), GlobalFilter, Ordered {
    companion object {
        private val logger = LoggerFactory.getLogger(this::class.java.declaringClass)
    }


    private fun getToken(request: ServerHttpRequest): String {
        var auth = request.findParameterValue("Authorization")
        if (auth.isNullOrEmpty()) {
            return ""
        }

        if (auth.contains(" ")) {
            return auth.split(" ").last()
        }

        return request.findParameterValue("token").AsString()
    }

    override fun filter(exchange_ori: ServerWebExchange, chain: GatewayFilterChain): Mono<Void> {
        var exchange = exchange_ori


        var request3 = exchange.request.mutate().headers {
            it.remove("user-id")
            it.remove("user-name")
            it.remove("user-login-name")
            it.remove("user-type")
            it.remove("tenant-id")
            it.remove("tenant-name")
        }.build()
        exchange = exchange.mutate().request(request3).build();


        if (ignoreFilter(exchange.request)) {
            return chain.filter(exchange);
        }

        var needIam = exchange.request.findParameterValue("iam").AsBooleanWithNull()
        if (needIam == false) {
            return chain.filter(exchange);
        }

        /**
         * 在 IAM 系统的 A，B 端， api-token
         */

        var token = getToken(exchange.request);

        if (token.isEmpty()) return chain.filter(exchange);

        var loginUserData: LoginUserModel? = getLoginUserFromToken(token);


        if (loginUserData == null) {
//            if (ignoreLog(exchange.request) == false) {
//                logger.Important("未解析到用户信息!token:${token}")
//            }

            return chain.filter(exchange);
        }


        var request2 = exchange.request.mutate().headers {
            it.set("user-id", loginUserData.id)
            it.set("login-name", loginUserData.loginName)
            it.set("user-name", UrlUtil.encodeURIComponent(loginUserData.name))
            it.set("user-type", loginUserData.system);
            it.set("tenant-id", loginUserData.tenantId)
            it.set("tenant-name", UrlUtil.encodeURIComponent(loginUserData.tenant.name))
        }.build()

        if (ignoreLog(exchange.request) == false) {
            logger.Important("token:${token},解析到用户: ${loginUserData.id}, ${loginUserData.loginName}, ${loginUserData.name}")
        }
        exchange = exchange.mutate().request(request2).build();

        return chain.filter(exchange);
    }

    private fun getLoginUserFromToken(token: String): LoginUserModel? {
//        var userSystem = token[0];
//        var tokenRedisKey = config.getConfig("app.${userSystem}-token.redis-key")
//        if (tokenRedisKey.HasValue) {
//            return rer.getString(tokenRedisKey!! + ":" + token, LoginUserModel::class.java);
//        }

        var tokenRedisKey = config.getConfig("app.token.redis-key")
        if (tokenRedisKey.HasValue) {
            for (key in tokenRedisKey!!.split(",")) {
                var loginUser = rer.getString(key + ":" + token, LoginUserModel::class.java);
                if (loginUser != null) {
                    return loginUser;
                }
            }
        }

//        var tokenUrl = config.getConfig("app.${userSystem}-token.http-url")
//
//        if (tokenUrl.HasValue) {
//            var fullUrl = tokenUrl + "?token=" + token;
//            var http = HttpRequestModel();
//            http.url = fullUrl
//            http.requestMethod = config.getConfig("app.${userSystem}-token.method").AsString("GET")
//            var result = http.doInvoke()
//            if (result.status == 401) {
//                return null;
//            }
//            if (result.status >= 400) {
//                logger.warn("请求 ${fullUrl} 出错, ${result.status}, msg: ${result.responseBody}")
//                return null;
//            }
//
//            var json = result.responseBody?.FromJson<ApiResult<LoginUserModel>>()
//            if (json == null) {
//                return null;
//            }
//
//            if (json.msg.HasValue) {
//                logger.warn("获取用户信息返回: " + result.responseBody)
//                return null;
//            }
//
//            return json.data;
//        }


//        tokenUrl = config.getConfig("app.token.http-url")
//        if (tokenUrl.HasValue) {
//            var fullUrl = tokenUrl + "?token=" + token;
//            var http = HttpRequestModel();
//            http.url = fullUrl
//            http.requestMethod = config.getConfig("app.token.method").AsString("GET");
//
//            var result = http.doInvoke()
//            if (result.status > 400) {
//                throw RuntimeException("请求 ${fullUrl} 出错, ${result.status}, msg: ${result.responseBody}");
//            }
//
//            return result.responseBody?.FromJson()
//        }


        return null;
    }

    override fun getOrder(): Int {
        return Ordered.HIGHEST_PRECEDENCE + 1;
    }
}